<template>
  <el-table
    header-row-class-name="base-table-header-v3"
    row-class-name="base-table-row-v3"
    :data="data"
    :border="border">
    <el-table-column
      v-for="(column, index) in columns"
      :key="`${column.fieldName}_${index}`"
      :label="column.displayName"
      :prop="column.fieldName"
      show-overflow-tooltip
      :width="column.width">
      <template slot-scope="scope">

        <!-- start 物料名称 -->
        <template v-if="column.fieldName === 'name'">
          <template v-if="canSelectMaterial" class="search-in-part">
            <biz-remote-select
              :placeholder="$t('common.placeholder.select')"
              :value="[scope.row]"
              :remote-method="fetchMaterial"
              @input="chooseMaterial($event, scope.row, scope.$index)"
            >
              <div class="search-in-part-item" slot="option" slot-scope="{ option }">
                <template v-if="option.name && !loading">
                  <p>{{$t('common.base.name')}}：<span>{{ option.name }}</span></p>
                  <p>{{$t('common.base.serialNumber：')}}<span>{{ option.sn }}</span></p>
                  <p>{{$t('task.detail.components.property')}}：<span>{{ option.property }}</span></p>
                </template>
                <p class="no_empty" v-else>{{ loading ? `${$t('common.base.loading')}`: `${$t('common.base.tip.noData')}` }}</p>
              </div>
            </biz-remote-select>
          </template>
          <template v-else>{{ scope.row[column.fieldName] }}</template>
        </template>
        <!-- end 物料名称 -->

        <template v-else-if="column.fieldName === 'serialNumber'">
          {{ scope.row.sn || scope.row.serialNumber }}
        </template>

        <!-- start 小计 -->
        <template v-else-if="column.fieldName === 'total'">
          {{ scope.row.salePrice && (scope.row.preNum * scope.row.salePrice).toFixed(2) }}
        </template>
        <!-- end 小计 -->

        <!-- start 预计用量 -->
        <template v-else-if="column.fieldName === 'preNum'">
          <el-input-number v-model="scope.row.preNum" step-strictly controls-position="right" :min="1" :max="materialListPreNumMax"></el-input-number>
        </template>
        <!-- end 预计用量 -->

        <!-- start 质保 -->
        <template v-else-if="column.fieldName === 'warrantyStatus'">
          <template v-if="allowWarrantyChange">
            <el-select
              v-model="scope.row.warrantyStatus"
              filterable>
              <el-option
                v-for="item in scope.row.warrantyStatusData"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              </el-option>
            </el-select>
          </template>
          <template v-else>{{ warrantyStatusMap[scope.row.warrantyStatusData] }}</template>
        </template>
        <!-- end 质保 -->

        <!-- start 出库仓库 -->
        <template v-else-if="column.fieldName === 'warehouse'">
          <el-select
            @change="chooseWarehouse($event, scope.row, scope.$index)"
            v-model="scope.row.warehouse"
            value-key="value"
            filterable
            :disabled="!allowSelectWarehouse">
            <el-option
              v-for="item in scope.row.warehouseData"
              :key="item.value"
              :label="item.label"
              :value="item">
            </el-option>
          </el-select>
        </template>
        <!-- end 出库仓库 -->

        <!-- start 出库仓位 -->
        <template v-else-if="column.fieldName === 'warehousePosition'">
          <el-select
            @change="chooseRepertory($event, scope.row)"
            v-model="scope.row.warehousePosition"
            value-key="value"
            filterable
            :disabled="!allowSelectWarehouse">
            <el-option
              v-for="item in scope.row.warehousePositionData"
              :key="item.value"
              :label="item.label"
              :value="item">
            </el-option>
          </el-select>
        </template>
        <!-- end 出库仓位 -->

        <!-- start 操作 -->
        <template v-else-if="column.fieldName === 'action'">
          <el-button class="text-danger" type="text" size="mini" @click="data.splice(scope.$index, 1)">{{$t('common.base.delete')}}</el-button>
        </template>
        <!-- end 操作 -->
        
        <!-- 状态 --> 
        <template v-else-if="column.fieldName === 'materialStatus'">
          {{ scope.row.materialStatus ? $t('common.base.open') : $t('common.base.disable') }}
        </template>

        <template v-else>
          <!-- {{ scope.row[column.fieldName] }} -->
          {{ $formatFormField(column, scope.row) }}
        </template>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
/* api */
import * as WareHouseApi from '@src/api/WareHouseApi';
/* model */
import { MATERIAL_LIST_PRENUM_MAX_LENGTH } from '@src/model/const/Number';

export default {
  name: 'material-table',
  props: {
    data: {
      type: Array,
      default: () => ([])
    },
    columns: {
      type: Array,
      default: () => ([])
    },
    border: {
      type: Boolean,
      default: false
    },
    // 可选择物料
    canSelectMaterial: {
      type: Boolean,
      default: false
    },
    type: {
      type: String,
      default: ''
    },
    // 允许物料申领时选择仓库
    allowSelectWarehouse: {
      type: Boolean,
      default: false
    },
    // 允许添加物料时修改物料质保状态
    allowWarrantyChange: {
      type: Boolean,
      default: false
    }
  },
  inject: ['initData'],
  data() {
    return {
      emptyData: {
        id: '',
        serialNumber: '',
        sn: '',
        name: '',
        property: '',
        unit: '',
        snManage: '',
        salePrice: '',
        preNum: '',
        sort: '',
        warehouseId: '',
        positionId: '',
        // 质保状态
        warrantyStatus: null
      },
      loading: false,
      materialListPreNumMax: MATERIAL_LIST_PRENUM_MAX_LENGTH,
      warrantyStatusMap: {
        0: this.$t('common.base.warranty'),
        1: this.$t('common.base.surrender')
      }
    }
  },
  methods: {
    /**
     * @description 添加一条表格数据
    */
    add() {
      if (this.data.length > 19) {
        return this.$message({
          showClose: true,
          message: this.$t('task.tip.addMaterialTip3', {max: 20}),
          type: 'error'
        })
      }

      this.data.push({...this.emptyData});
    },
    /**
     * @description 搜索物料
    */
    async fetchMaterial(params) {
      this.loading = true;
      const { keyword, pageNum, pageSize } = params
      try {
        let model = {
          keyword,
          pageNum,
          pageSize
        }
        let res = await WareHouseApi.getMaterialList(model);
        this.loading = false;
        if (!res.success) return;
        res.data.list = res.data.list.map(item => {
          return {
            label: item.name,
            value: item.id,
            ...item,
          }
        });

        return res.data;
      } catch (error) {
        this.loading = false;
        console.warn('fetchMaterial -> error', error);
      } 
    },
    /**
     * @description 选择物料
    */
    chooseMaterial(value, row, index) {
      let selectedMaterial = value?.[0] || {};
      if(!selectedMaterial.id) return;
      
      // 判断当前选择的物料是否已经存在, 排除本身
      let idx = this.data.findIndex(item => item.id == selectedMaterial.id);
      if(idx > -1 && idx != index) return this.$platform.toast(this.$t('task.tip.chooseMaterialTip'), 'warning');

      Object.keys(this.emptyData).forEach(key => {
        if (key == 'preNum') {
          row[key] = 1;
        } else if(key == 'sort') {
          row[key] = selectedMaterial.type || '';
        } else if(key === 'serialNumber') {
          row[key] = selectedMaterial.sn || '';
        } else if(key === 'salePrice') {
          row[key] = selectedMaterial.salePrice || 0
        } else {
          row[key] = selectedMaterial[key];
        }
      })
    },
    /**
    * @description 选择仓库
    */
    chooseWarehouse(value, row, index) {
      this.$set(row, 'warehouseId', value.value)
      this.$set(row, 'warehousePosition', {})
      this.$set(row, 'availableNum', 0)
      this.getDefaultWarehousePosition(row.warehouseId, index)
    },
    /**
    * @description 选择仓位
    */
    chooseRepertory(value, row) {
      this.$set(row, 'positionId', value.value)
      let inventoryParams = {
        warehouseId: row.warehouseId,
        positionId: row.positionId,
        // 物料id需要兼容多个字段名
        materialId: row.relatedId
      }
      this.getInventoryList(inventoryParams)
    },
    /** 
     * @description 获取默认仓位 
    */
    getDefaultWarehousePosition(warehouseId, index) {
      // TODO 这个接口好像有问题，但是暂时没发现项目中有页面使用该组件，就没改动，后续参考bug 19594。
      WareHouseApi.getWarehousePositionListSearch({ warehouseId })
        .then((result) => {
          if (result?.success) {
            let data = result?.data?.list || []
            let warehousePositionList = data.map(item => {
              return {
                label: item.name,
                value: item.id
              }
            })
            this.$set(this.data[index], 'warehousePositionData', warehousePositionList)
          }
        }).catch(error => {
          console.error(error);
        })
    },
    /** 
     * @description 获取可用库存 
    */
    getInventoryList(inventoryParams) {
      let params = {
        ...inventoryParams
      }
      WareHouseApi.getInventoryList(params)
        .then(result => {
          if (result?.success) {
            let list = result?.data?.list || []
            list.forEach(material => {
              let index = this.data.findIndex(item => item.relatedId == material.materialId)
              if(index > -1) {
                this.$set(this.data[index], 'availableNum', material.availableNum)
              }
            })
          }
        }).catch(error => {
          console.error(error)
        })
    }
  }
}
</script>

<style lang="scss">
  .search-in-part-item {
    padding: 8px 5px 8px 0;
    overflow: hidden;
    max-width: 260px;
    p {
      /*@include text-ellipsis();*/
      line-height: 20px;
      margin: 0 16px 0 0;
      // color: $text-color-primary;
      white-space: initial;
      span {
        // color: $text-color-regular;
      }
    }

    .no_empty {
      padding: 0;
      text-align: center;
      color: #999;
      font-size: 14px;
    }
  }
</style>

<style lang="scss" scoped>
input[type="number"],
.el-autocomplete {
  width: 99%;
}

.el-table {
  &::before {
    content: "";
  }
}
</style>